home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / HippoDraw / hippo / hippoutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-28  |  9.7 KB  |  517 lines

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "hippo.h"
  5. #ifdef VM
  6. #include "h_util.h"
  7. #else
  8. #include "hippoutil.h"
  9. #endif
  10.  
  11. GLOB_QUAL const char hippoutil_c_rcsid[] = "$Id: hippoutil.c,v 3.3 1992/03/21 01:52:25 rensing Rel $";
  12.  
  13. /*
  14.  * Structures for the function registry.
  15.  */
  16.  
  17. struct func_strt { 
  18.      char name[FUNCNAMELEN+1]; 
  19.      void *func;
  20. };
  21.  
  22. static struct func_strt f_list1[] = {
  23. { "h_cut_lt", h_cut_lt },
  24. { "h_cut_gt", h_cut_gt },
  25. { "h_cut_le", h_cut_le },
  26. { "h_cut_ge", h_cut_ge },
  27. { "h_cut_inside", h_cut_inside },
  28. { "h_cut_outside", h_cut_outside },
  29. { "h_cut_in_incl", h_cut_in_incl },
  30. { "h_cut_out_incl", h_cut_out_incl },
  31. { "", (void *)NULL } };        /* must terminate with NULL */
  32.  
  33. static struct func_strt *f_list2 = NULL;
  34.  
  35. static int func_list_l = 0;
  36.  
  37.  
  38. /*
  39.  * Search for the function name, return its pointer.
  40.  *   Return NULL if not found.
  41.  */
  42. void *h_fNameSrch(const char *fname)
  43. {
  44.      int i = 0;
  45.      
  46.      while( f_list1[i].func != NULL )
  47.      {
  48.       if (strncmp(f_list1[i].name,fname,FUNCNAMELEN) == 0)
  49.            return f_list1[i].func;
  50.       i++;
  51.      }
  52.  
  53.      if (f_list2 != NULL)
  54.      {
  55.       i = 0;
  56.       while( f_list2[i].func != NULL )
  57.       {
  58.            if (strncmp(f_list2[i].name,fname,FUNCNAMELEN) == 0)
  59.             return f_list2[i].func;
  60.            i++;
  61.       }
  62.      }
  63.      
  64.      return NULL;
  65. }
  66.  
  67. /*
  68.  * Search for the function pointer, return its name if found.
  69.  */
  70. char *h_fPtrSrch(void *func)
  71. {
  72.      int i = 0;
  73.      
  74.      while( f_list1[i].func != NULL )
  75.      {
  76.       if (f_list1[i].func == func)
  77.            return f_list1[i].name;
  78.       i++;
  79.      }
  80.      
  81.      if (f_list2 != NULL)
  82.      {
  83.       i = 0;
  84.       while( f_list2[i].func != NULL )
  85.       {
  86.            if (f_list2[i].func == func)
  87.             return f_list2[i].name;
  88.            i++;
  89.       }
  90.      }
  91.  
  92.      return NULL;
  93. }
  94.  
  95.  
  96. /*
  97.  * Register the function on the registry.
  98.  */
  99. int h_func_reg(const char *fn, void *func)
  100. {
  101.      int i=0;
  102.      char *sname;
  103.      void *sfunc;
  104.      
  105.      if ((sname = h_fPtrSrch(func)) != NULL)
  106.       if (sname != fn)
  107.       {
  108.            h_error("h_funcReg: function name is in registry, but pointer does not match.");
  109.            return -1;
  110.       }
  111.            else
  112.            return 0;
  113.  
  114.      if ((sfunc = h_fNameSrch(fn)) != NULL)
  115.       if (sfunc != func)
  116.       {
  117.            h_error("h_funcReg: function pointer is in registry, but name does not match.");
  118.            return -1;
  119.       }
  120.            else
  121.            return 0;
  122.  
  123.      if (func_list_l == 0)
  124.      {
  125.       f_list2 = (struct func_strt *)
  126.            malloc( (size_t)5*sizeof(struct func_strt) );
  127.       if (f_list2 == NULL)
  128.       {
  129.            h_error("h_funcReg: Error allocating memory for function registry.");
  130.            return -1;
  131.       }
  132.       func_list_l = 5;
  133.       i = 0;
  134.      }
  135.      else
  136.      {
  137.       while( f_list1[i].func != NULL ) i++;
  138.       if (i==(func_list_l-1))
  139.       {
  140.            f_list2 = (struct func_strt *)
  141.             realloc( f_list2, 
  142.                 (size_t)(func_list_l+5)*sizeof(struct func_strt) );
  143.            if (f_list2 == NULL)
  144.            {
  145.             h_error("h_funcReg: Error reallocating memory for function registry");
  146.             return -1;
  147.            }
  148.            func_list_l += 5;
  149.       }
  150.      }
  151.  
  152.      strncpy(f_list2[i].name,fn,FUNCNAMELEN);
  153.      f_list2[i].func = func;
  154.  
  155.      strncpy(f_list2[i+1].name,"",FUNCNAMELEN);
  156.      f_list2[i+1].func = (void*)NULL;
  157.      
  158.      
  159.      return 0;
  160. }
  161.  
  162. void h_adjustAxis( float *low, float *high, int nbins, int log )
  163. {
  164.      int i;
  165.      int axis = 0;
  166.      float step, w, mag, range;
  167.      float mylow, myhigh;
  168. #define N_NICE 4
  169. #ifndef __STDC__
  170.      static
  171. #endif
  172.      float nice[N_NICE] = { 1.0,2.0,2.5,5.0 };
  173.       
  174.      if (*low >= *high) 
  175.      {
  176.       if (*low < 0.0) *high = 0.0;
  177.       else if (*low > 0.0) *low = 0.0;
  178.       else 
  179.       {
  180.            *low = -1.0;
  181.            *high = 1.0;
  182.            return;
  183.       }
  184.      }
  185.      
  186.      if (nbins <= 0) 
  187.      {
  188.       axis = 1;
  189.       nbins = 10;
  190.      }
  191.      
  192.      /*
  193.       * Round the "bin width" to a nice number.
  194.       * If this is being done for an axis (ie nbins was 0), then
  195.       * we don't have to go > *high.
  196.       */
  197.      w = (*high - *low)/((float)nbins);
  198.      mag = floor(log10(w));
  199.      i = 0;
  200.      do
  201.      {
  202.       step = nice[i] * pow(10.0,mag);
  203.      
  204.       mylow = floor(*low/step) * step;
  205.       if (!axis)
  206.            myhigh = mylow + step*nbins;
  207.       else
  208.            myhigh = ceil(*high/step) * step;
  209.       
  210.  
  211.       i++;
  212.       if (i>=N_NICE) 
  213.       {
  214.            i = 0;
  215.            mag++;
  216.       }
  217.      }
  218.      while ( (axis && myhigh < *high) || (!axis && myhigh <= *high) );
  219.  
  220.      range = myhigh - mylow;
  221.      
  222.      /*
  223.       * we now have decided on a range. Try to move low/high a little
  224.       *  to end up on a nice number.
  225.       *
  226.       * first check if either end is near 0.0
  227.       */
  228.      if (!log && *low >= 0.0 && 
  229.      ((axis && range>=*high) || (!axis && range>*high)) )
  230.      {
  231.       *low = 0.0;
  232.       *high = range;
  233.       return;
  234.      }
  235.      if ( ((axis && *high<=0.0) || (!axis && *high<0.0)) 
  236.      && -range<=*low)
  237.      {
  238.       *high = 0.0;
  239.       *low = -range;
  240.       return;
  241.      }
  242.  
  243.      /*
  244.       * try to round *low.
  245.       */
  246.      i = N_NICE-1;
  247.      if (myhigh != 0.0)
  248.       mag = ceil(log10(fabs(myhigh)));
  249.      else
  250.       mag = ceil(log10(fabs(mylow)));
  251.      
  252.      do
  253.      {
  254.       step = nice[i] * pow(10.0,mag);
  255.      
  256.       mylow = floor(*low/step) * step;
  257.       myhigh = mylow + range;
  258.  
  259.       i--;
  260.       if (i<0) 
  261.       {
  262.            i = N_NICE-1;
  263.            mag--;
  264.       }
  265.      } 
  266.      while ((log && mylow <= 0.0) || 
  267.         (axis && myhigh < *high) || 
  268.         (!axis && myhigh <= *high) );
  269.  
  270.      *low = mylow;
  271.      *high = myhigh;
  272.      return;
  273. }
  274. #undef N_NICE
  275.  
  276.  
  277. /*
  278.  * Hippo error message facility.
  279.  */
  280. void h_errmsg(const char *file, int line, const char *msg )
  281. {
  282.      fprintf(stderr, "Error in hippo file %s, line %d :\n", file, line);
  283.      fprintf(stderr, "     %s\n", msg );
  284. }
  285.  
  286.  
  287. /*
  288.  * Title expansion routine. Parse string for such things as 
  289.  * %t, %x, %y, etc.
  290.  */
  291. char *h_expandLabel( char *dest, const char *src, int max, display disp )
  292. {
  293.      int i,j=0;
  294.      int bind;
  295.      int l;
  296.      int k;
  297.      float del,del2;
  298.      char form[15];
  299.      
  300.      l = strlen(src);
  301.  
  302.      if (disp->ntuple == NULL)
  303.      {
  304.       strncpy( dest, src, max );
  305.       return dest;
  306.      }
  307.      
  308.      for (i=0; i<l && j<max; i++)
  309.      {
  310.       if (src[i] == '%')
  311.       {
  312.            i++;
  313.            switch (src[i])
  314.            {
  315.            case '%':
  316.             dest[j++] = '%';
  317.             break;
  318.             
  319.            case 't': case 'T':
  320.             if (disp->ntuple->title != NULL)
  321.             {
  322.              strncpy(&(dest[j]),disp->ntuple->title,max-j-1);
  323.              j = strlen(dest);
  324.             }
  325.             break;
  326.             
  327.            case 'x': case 'X':
  328.             if ((bind = disp->binding.x) >= 0)
  329.             {
  330.              strncpy(&(dest[j]),disp->ntuple->label[bind],max-j-1);
  331.              j = strlen(dest);
  332.             }
  333.             break;
  334.  
  335.            case 'y': case 'Y':
  336.             if ((bind = disp->binding.y) >= 0)
  337.             {
  338.              strncpy(&(dest[j]),disp->ntuple->label[bind],max-j-1);
  339.              j = strlen(dest);
  340.             }
  341.             break;
  342.  
  343.            case 'z': case 'Z':
  344.             if ((bind = disp->binding.z) >= 0)
  345.             {
  346.              strncpy(&(dest[j]),disp->ntuple->label[bind],max-j-1);
  347.              j = strlen(dest);
  348.             }
  349.             break;
  350.             
  351.            case 'w': case 'W':
  352.             if ((bind = disp->binding.weight) >= 0)
  353.             {
  354.              strncpy(&(dest[j]),disp->ntuple->label[bind],max-j-1);
  355.              j = strlen(dest);
  356.             }
  357.             break;
  358.             
  359.            case 'd': case 'D':
  360.             i++;
  361.             switch (src[i])
  362.             {
  363.             case 'x': case 'X':
  364.              del = (disp->xAxis.high-disp->xAxis.low)
  365.                   /(float)disp->bins.xAxis.nBins;
  366.              for (k=1; k<6; k++)
  367.              {
  368.                   del2 = del*pow(10.0,(double)k);
  369.                   if (fabs((int)del2 - del2) < 1e-2) break;
  370.              }
  371.              sprintf(form,"%%1.%df",k);
  372.              sprintf(&dest[j],form,del);
  373.              j = strlen(dest);
  374.              break;
  375.              
  376.             case 'y': case 'Y':
  377.              del = (disp->yAxis.high-disp->yAxis.low)
  378.                   /(float)disp->bins.yAxis.nBins;
  379.              for (k=1; k<6; k++)
  380.              {
  381.                   del2 = del*pow(10.0,(double)k);
  382.                   if (fabs((int)del2 - del2) < 1e-2) break;
  383.              }
  384.              sprintf(form,"%%1.%df",k);
  385.              sprintf(&dest[j],form,del);
  386.              j = strlen(dest);
  387.              break;
  388.             }
  389.             break;
  390.             
  391.            case 'e': case 'E':
  392.             i++;
  393.             switch (src[i])
  394.             {
  395.             case 'x': case 'X':
  396.              if ((bind = disp->binding.xerror) >= 0)
  397.              {
  398.                   strncpy(&(dest[j]),disp->ntuple->label[bind],
  399.                       max-j-1);
  400.                   j = strlen(dest);
  401.              }
  402.              break;
  403.              
  404.             case 'y': case 'Y':
  405.              if ((bind = disp->binding.yerror) >= 0)
  406.              {
  407.                   strncpy(&(dest[j]),disp->ntuple->label[bind],
  408.                       max-j-1);
  409.                   j = strlen(dest);
  410.              }
  411.              break;
  412.             }
  413.             break;
  414.            }
  415.       }
  416.       else
  417.            dest[j++] = src[i];
  418.      }
  419.  
  420.      if (j<max)
  421.       dest[j] = '\0';
  422.      else 
  423.       dest[max-1] = '\0';
  424.  
  425.      return dest;
  426. }
  427.  
  428.  
  429. /*
  430.  * Standard Cut functions.
  431.  */
  432.  
  433. int h_cut_lt( float nt[], double param[] )
  434. {
  435.      if (nt[ (int)param[0] ] < param[1])
  436.       return 1;
  437.      else
  438.       return 0;
  439. }
  440.  
  441. int h_cut_gt( float nt[], double param[] )
  442. {
  443.      if (nt[ (int) param[0]] > param[1] )
  444.       return 1;
  445.      else
  446.       return 0;
  447. }
  448.  
  449. int h_cut_le( float nt[], double param[] )
  450. {
  451.      if (nt[ (int) param[0]] <= param[1] )
  452.       return 1;
  453.      else
  454.       return 0;
  455. }
  456.  
  457. int h_cut_ge( float nt[], double param[] )
  458. {
  459.      if (nt[ (int) param[0]] >= param[1] )
  460.       return 1;
  461.      else
  462.       return 0;
  463. }
  464.  
  465. int h_cut_inside( float nt[], double param[] )
  466. {
  467.      if (nt[(int) param[0]] > param[1] &&
  468.      nt[(int) param[0]] < param[2])
  469.       return 1;
  470.      else
  471.       return 0;
  472. }
  473.  
  474. int h_cut_outside( float nt[], double param[] )
  475. {
  476.      if (nt[(int) param[0]] < param[1] ||
  477.      nt[(int) param[0]] > param[2])
  478.       return 1;
  479.      else
  480.       return 0;
  481. }
  482.  
  483. int h_cut_in_incl( float nt[], double param[] )
  484. {
  485.      if (nt[(int) param[0]] >= param[1] &&
  486.      nt[(int) param[0]] <= param[2])
  487.       return 1;
  488.      else
  489.       return 0;
  490. }
  491.  
  492. int h_cut_out_incl( float nt[], double param[] )
  493. {
  494.      if (nt[(int) param[0]] <= param[1] ||
  495.      nt[(int) param[0]] >= param[2])
  496.       return 1;
  497.      else
  498.       return 0;
  499. }
  500.  
  501.  
  502. int doCuts( float nt[], func_id cutlist )
  503. {
  504.      typedef int (*cutfunc)(float *,double *);
  505.       
  506.      func_id c = cutlist;
  507.      int result = 0;
  508.      
  509.      while (c != NULL)
  510.      {
  511.       result += (*((cutfunc)c->funcPtr))( nt, (double *)c->paramBlk );
  512.       c = c->next;
  513.      }
  514.  
  515.      return result;
  516. }
  517.